﻿using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System;
using System.IO;

namespace SafeFile.Ciphers
{
    internal class RSA
    {
        public static void MakeKeys(string path)
        {
            // 创建 RSA 密钥对生成器
            var keyGenerator = new RsaKeyPairGenerator();

            // 设置密钥大小（例如，1024 位）
            var keyGenParam = new KeyGenerationParameters(new SecureRandom(), 4096);
            keyGenerator.Init(keyGenParam);
            //keyGenerator.siz = 1024;

            // 生成 RSA 密钥对
            var keyPair = keyGenerator.GenerateKeyPair();

            // 获取公钥和私钥
            var publicKey = keyPair.Public as RsaKeyParameters;
            var privateKey = keyPair.Private as RsaKeyParameters;

            var time = DateTime.Now.ToString("yyyyMMdd_HHmmss_");

            // 将公钥写入文件
            string publicKeyPath = Path.Combine(path, $"{time}_发给对方_加密.key");
            using (StreamWriter writer = new StreamWriter(publicKeyPath))
            {
                var pemWriter = new PemWriter(writer);
                pemWriter.WriteObject(publicKey);
                pemWriter.Writer.Flush();
            }

            // 将私钥写入文件
            string privateKeyPath = Path.Combine(path, $"{time}_禁止外发_解密.key");
            using (StreamWriter writer = new StreamWriter(privateKeyPath))
            {
                var pemWriter = new PemWriter(writer);
                pemWriter.WriteObject(privateKey);
                pemWriter.Writer.Flush();
            }
        }

        public static RsaKeyParameters ReadKey(string filename, bool isPrivate = false)
        {
            using (StreamReader reader = new StreamReader(filename))
            {
                PemReader pemReader = new PemReader(reader);
                var obj = pemReader.ReadObject();

                if (obj is RsaKeyParameters)
                {
                    return (RsaKeyParameters)obj;
                }

                //if (isPrivate)
                //{
                //    return (RsaKeyParameters)(obj.Private);
                //}
                //return (RsaKeyParameters)(obj.Public);
                var pair = (AsymmetricCipherKeyPair)obj;
                return (RsaKeyParameters)pair.Private;
            }
        }

        public static byte[] Encrypt(byte[] data, int length, RsaKeyParameters key)
        {
            var engine = new RsaEngine();
            engine.Init(true, key);
            var result = engine.ProcessBlock(data, 0, length);

            return result;
        }

        public static byte[] Decrypt(byte[] data, RsaKeyParameters key)
        {
            var engine = new RsaEngine();
            engine.Init(false, key);
            var result = engine.ProcessBlock(data, 0, data.Length);

            return result;
        }
    }
}

